﻿/*
Copyright © 2011 François Karman

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

See <license.txt> for the complete license of the software.
*/

using System;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Phone.Controls;

namespace NUnit.Phone.Gui
{
    /// <summary>
    /// The entry point of the NUnit tests display.
    /// </summary>
    public partial class MainView : UserControl
    {
        /// <summary>
        /// Identifies the <see cref="MainView.AppTitle"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty AppTitleProperty =
            DependencyProperty.Register("AppTitle", typeof(string), typeof(MainView), new PropertyMetadata("NUNIT 4 PHONE"));

        /// <summary>
        /// The default format used to create uris.
        /// </summary>
        private const string UriFormat = "{0}?{1}={2}";

        /// <summary>
        /// The page associated with the current control.
        /// </summary>
        private PhoneApplicationPage page;

        /// <summary>
        /// Initializes a new instance of the TestView class.
        /// </summary>
        public MainView()
        {
            this.InitializeComponent();
        }

        /// <summary>
        /// Gets or sets the title of the application.
        /// </summary>
        public string AppTitle
        {
            get { return (string)this.GetValue(AppTitleProperty); }
            set { this.SetValue(AppTitleProperty, value); }
        }

        /// <summary>
        /// Gets the page associated with the current control.
        /// </summary>
        public PhoneApplicationPage Page
        {
            get
            {
                if (this.page == null)
                {
                    this.page = this.RetrieveParent<PhoneApplicationPage>();
                }

                return this.page;
            }
        }

        /// <summary>
        /// Reload the page with a specific parameter.
        /// </summary>
        /// <param name="name">The name of the parameter.</param>
        /// <param name="value">The value of the parameter.</param>
        public void Reload(string name, string value)
        {
            // Extract the name of the page from the current navigation source
            string fullPath = this.Page.NavigationService.CurrentSource.OriginalString;
            string pageUri;
            if (fullPath.Contains("?"))
            {
                pageUri = fullPath.Substring(0, fullPath.IndexOf("?"));
            }
            else
            {
                pageUri = fullPath;
            }

            string uriString = string.Format(CultureInfo.InvariantCulture, UriFormat, pageUri, name, value);
            Uri destination = new Uri(uriString, UriKind.Relative);
            this.Page.NavigationService.Navigate(destination);
        }

        /// <summary>
        /// Called when the control is 'arranged' - used to initialize the
        /// data context prior the first display of the control.
        /// </summary>
        /// <param name="finalSize">The final size of the component.</param>
        /// <returns>The used size.</returns>
        protected override Size ArrangeOverride(Size finalSize)
        {
            this.InitializeDataContext();
            return base.ArrangeOverride(finalSize);
        }

        /// <summary>
        /// Called when the 'start all tests' button is clicked.
        /// </summary>
        /// <param name="sender">The parameter is not used.</param>
        /// <param name="e">The parameter is not used.</param>
        private void OnStartClick(object sender, RoutedEventArgs e)
        {
            this.Reload("result", "true");
        }

        /// <summary>
        /// Called when the 'show result list' button is clicked.
        /// </summary>
        /// <param name="sender">The parameter is not used.</param>
        /// <param name="e">The parameter is not used.</param>
        private void OnShowResultListClick(object sender, RoutedEventArgs e)
        {
            this.Reload("result", "true");
        }

        /// <summary>
        /// Initializes the associated view model based on the parameters
        /// of the page.
        /// </summary>
        private void InitializeDataContext()
        {
            if (this.DataContext != null)
            {
                // already initialized
                return;
            }

            // Load the test that should be displayed, set by default to the root test
            int identifier = TestManager.Instance.RootTest.Id;
            if (this.Page.NavigationContext.QueryString.ContainsKey("testid"))
            {
                string str = this.Page.NavigationContext.QueryString["testid"];
                if (!string.IsNullOrEmpty(str))
                {
                    int.TryParse(str, out identifier);
                }
            }

            // Check if the result should be displayed
            bool displayResult = false;
            if (this.Page.NavigationContext.QueryString.ContainsKey("result"))
            {
                if (string.Equals("true", this.Page.NavigationContext.QueryString["result"], StringComparison.OrdinalIgnoreCase))
                {
                    displayResult = true;
                }
            }
            else if (TestManager.Instance.AutoStart)
            {
                displayResult = true;
            }

            if (displayResult)
            {
                this.list.Visibility = Visibility.Collapsed;
                this.resultList.Visibility = Visibility.Visible;
                ResultListViewModel.Instance.ExecuteStart();
            }

            this.DataContext = new MainViewModel(identifier, displayResult);
        }
    }
}
